# -*- coding: UTF-8 -*- #
"""
@filename:01-5鼠标交互与响应.py
@author:JiYujia
@time:2022-09-04
"""

# # 鼠标事件
# # CV_EVENT_FLAG_LBUTTON 1       //左键拖拽
# # CV_EVENT_FLAG_RBUTTON 2       //右键拖拽
# # CV_EVENT_FLAG_MBUTTON 4       //中键拖拽
# # CV_EVENT_FLAG_CTRLKEY 8       //Ctrl按下不放
# # CV_EVENT_FLAG_SHIFTKEY 16     //shift按下不放
# # CV_EVENT_FLAG_ALTKEY 32       //alt按下不放
# #
# # CV_EVENT_MOUSEMOVE      0,   //鼠标移动
# # CV_EVENT_LBUTTONDOWN    1,   //按下左键
# # CV_EVENT_RBUTTONDOWN    2,   //按下右键
# # CV_EVENT_MBUTTONDOWN    3,   //按下中键
# # CV_EVENT_LBUTTONUP      4,   //放开左键
# # CV_EVENT_RBUTTONUP      5,   //放开右键
# # CV_EVENT_MBUTTONUP      6,   //放开中键
# # CV_EVENT_LBUTTONDBLCLK  7,   //左键双击
# # CV_EVENT_RBUTTONDBLCLK  8,   //右键双击
# # CV_EVENT_MBUTTONDBLCLK  9,   //中键双击
# # CV_EVENT_MOUSEWHEEL     10,  //滚轮滚动
# # CV_EVENT_MOUSEHWHEEL    11   //横向滚轮滚动

import cv2 as cv
import numpy as np

ox = 0
oy = 0
sx = 0
sy = 0

# Python变量的作用域一共有4种，分别是：
#
# L （Local） 局部作用域
# E （Enclosing） 闭包函数外的函数中
# G （Global） 全局作用域
# B （Built-in） 内建作用域 以 L –> E –> G –>B 的规则查找，即：在局部找不到，便会去局部外的局部找（例如闭包），再找不到就会去全局找，再者去内建中找。

def draw_rectangle(event, x, y, flags, param):
    global img
    global ox, oy, sx, sy

    # 发生鼠标左键双击事件->改变背景颜色
    if event == cv.EVENT_LBUTTONDBLCLK:
        img = np.ones((500, 500, 3), np.uint8) * 200

    # 鼠标没有移动且单击
    elif event != cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON:
        sx, sy = x, y
        ox, oy = x, y
        print('x:', x, 'y:', y)
    # 鼠标移动且单击——画直线并获取坐标
    elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON:
        cv.line(img, (ox, oy), (x, y), (255, 255, 255), 3, cv.LINE_AA)
        ox, oy = x, y
    # 鼠标不移动不单击——画矩形
    elif event != cv.EVENT_MOUSEMOVE and flags != cv.EVENT_FLAG_LBUTTON:
        cv.rectangle(img, (sx, sy), (x, y), (255, 0, 255), 3, cv.LINE_AA)

# 创建窗体
cv.namedWindow('image')
cv.setMouseCallback('image', draw_rectangle)

# 创建图像矩阵
img = np.zeros((500, 500, 3), np.uint8)

while True:
    cv.imshow('image', img)
    k = cv.waitKey(25) & 0xff
    if chr(k) == 'q':
        break
